using System;
using System.Collections;
using Sloppycode.net;
using System.Xml.Serialization;
using System.IO;

namespace RssAggregator
{
	/// <summary>
	/// RssFeedStore
	/// Version: 0.1   draft
	/// Copyright 2004 (c) Stephan Meyn
	/// Role: a store for RSS Feeds
	/// Responsibilities:
	/// <list type="bullet">
	/// <item>knows individual RSS Feeds</item>
	/// <item>knows status of feeds</item>
	/// </list>
	/// </summary>
	public class RssFeedStore
	{
		#region private fields
		/// <summary>
		/// the RssFeed items are contained here by name
		/// </summary>
		private Hashtable feeds;
		#endregion

		#region public Attributes
		/// <summary>
		/// list of all RssFeeds registered
		/// </summary>
		public ICollection Urls { get { return feeds.Keys; } }

		/// <summary>
		/// index into a particular RssFeed
		/// </summary>
		public RssFeed this[string url] { get { return feeds[url] as RssFeed;} set {feeds[url] = value;}}

		public Hashtable Feeds { get { return feeds; } set { feeds = value;}}
		#endregion

		#region construction
		public RssFeedStore()
		{
			feeds = new Hashtable();
		}
		#endregion
		
		

		#region public methods
		/// <summary>
		/// add a feed URL
		/// </summary>
		/// <param name="URL"></param>
		public void AddFeed(string URL)
		{
			if (!feeds.ContainsKey(URL))
			{
				RssFeed emptyFeed = new RssFeed();
				emptyFeed.Link = URL;
				feeds.Add(URL, emptyFeed);
			}
		}
		/// <summary>
		/// remove a feed URL and the most recent feed
		/// </summary>
		/// <param name="URL"></param>
		public void RemoveFeed(string URL)
		{
			if (feeds.ContainsKey(URL))
				feeds.Remove(URL);
		}

		#region RssPersistence
		[Obsolete]public void Save2Xml(string path)
		{
			RssFeed[] feeds2Store = new RssFeed[feeds.Count];
			int idx=0;
			foreach (string url in feeds.Keys)
			{
				feeds2Store[idx] = (RssFeed) feeds[url];
				feeds2Store[idx++].Link = url;
			}
			
			XmlSerializer serializer = new XmlSerializer(typeof(RssFeed[]), "RssAggregator");
			using (TextWriter writer = new StreamWriter(path))
			{
				lock(this)  // lock against updates to store
				{
					try
					{
						serializer.Serialize(writer, feeds2Store);
					}
					catch (Exception ex)
					{
						Console.WriteLine("failed to write Xml to '{0}'", path);
						Console.WriteLine(ex.Message);
					}
				}
			}
		}

		/// <summary>
		/// restore from file those feeds that have a URL here
		/// </summary>
		/// <param name="path"></param>
		[Obsolete]public void ReStore(string path)
		{
			if (!File.Exists(path))
				return;
			FileStream fs = null;
			try
			{
				// Create an instance of the XmlSerializer class;
				// specify the type of object to be deserialized.
				XmlSerializer serializer = new XmlSerializer(typeof(RssFeed[]));
				/* If the XML document has been altered with unknown 
				nodes or attributes, handle them with the 
				UnknownNode and UnknownAttribute events.*/
				//			serializer.UnknownNode+= new 
				//				XmlNodeEventHandler(serializer_UnknownNode);
				//			serializer.UnknownAttribute+= new 
				//				XmlAttributeEventHandler(serializer_UnknownAttribute);
				//   
				// A FileStream is needed to read the XML document.
				fs = new FileStream(path, FileMode.Open);
				// Declare an object variable of the type to be deserialized.				
				/* Use the Deserialize method to restore the object's state with
				data from the XML document. */
				RssFeed[] feeds2Load =  (RssFeed[]) serializer.Deserialize(fs);
				lock(this)
				{
					feeds = new Hashtable();
					foreach (RssFeed feed in feeds2Load)
					{
						if (feeds.ContainsKey(feed.Link))
							feeds[feed.Link] = feed;
					}
				}
			}
			catch (Exception ex)
			{
				Console.WriteLine(ex);
			}
			finally
			{
				if (fs != null)
					fs.Close();
			}

		}

		#endregion
		#endregion

	}
}
